use std::sync::Arc;
use tokio::sync::RwLock;
use anyhow::Result;

use crate::config::{AppConfig, load_config};

/// 简化的配置管理器，支持手动热加载
#[derive(Clone)]
pub struct ConfigManager {
    config: Arc<RwLock<AppConfig>>,
}

impl ConfigManager {
    /// 创建新的配置管理器
    pub fn new() -> Result<Self> {
        let config = Arc::new(RwLock::new(load_config()?));
        
        Ok(Self {
            config,
        })
    }
    
    /// 获取当前配置的只读引用
    pub async fn get_config(&self) -> Arc<RwLock<AppConfig>> {
        self.config.clone()
    }
    
    /// 手动重新加载配置
    pub async fn reload_config(&self) -> Result<()> {
        let new_config = load_config()?;
        *self.config.write().await = new_config;
        println!("配置已手动重新加载");
        Ok(())
    }
    
    /// 更新特定配置项
    pub async fn update_config<F>(&self, updater: F) -> Result<()> 
    where
        F: FnOnce(&mut AppConfig),
    {
        let mut config = self.config.write().await;
        updater(&mut config);
        println!("配置已动态更新");
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    
    #[tokio::test]
    async fn test_config_manager_creation() {
        let manager = ConfigManager::new().unwrap();
        let config = manager.get_config().await;
        let config_guard = config.read().await;
        
        assert_eq!(config_guard.server.port, 8080);
        assert_eq!(config_guard.server.host, "0.0.0.0");
    }
    
    #[tokio::test]
    async fn test_config_update() {
        let manager = ConfigManager::new().unwrap();
        
        // 测试配置更新
        manager.update_config(|config| {
            config.server.port = 9090;
        }).await.unwrap();
        
        let config = manager.get_config().await;
        let config_guard = config.read().await;
        assert_eq!(config_guard.server.port, 9090);
    }
}